#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/sysinfo.h>
#include "common_util.h"

// 将二进制数据转换为16进制字符串
void bin_to_hexstr(const unsigned char *bin, size_t len, char *hexstr) {
    for (size_t i = 0; i < len; ++i) {
        sprintf(hexstr + (i * 2), "%02x", bin[i]);
    }
    hexstr[len * 2] = '\0';  // 添加字符串结束符
}

// 将16进制字符串转换为二进制数据
void hexstr_to_bin(const char *hexstr, unsigned char *bin, size_t *len) {
    size_t hexstr_len = strlen(hexstr);
    *len = hexstr_len / 2;  // 输出的二进制长度
    for (size_t i = 0; i < *len; ++i) {
        sscanf(hexstr + (i * 2), "%02hhx", &bin[i]);
    }
}

int isValidIPv4(const char *ip) {
    if (ip == NULL) return 0;
    if (strlen(ip) != 15) return 0;
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ip, &(sa.sin_addr));
    return result == 1 ? 1 : 0;
}

int isValidIPv6(const char *ipv6) {
    if (ipv6 == NULL) return 0;
    struct sockaddr_in6 sa6;
    int result = inet_pton(AF_INET6, ipv6, &(sa6.sin6_addr));
    return result == 1 ? 1 : 0;
}

void get_usage(long *virtual_memory, long *physical_memory, double *cpu) 
{
    FILE *file;
    char buffer[128];

    // 读取虚拟内存使用（从 /proc/self/statm）
    file = fopen("/proc/self/statm", "r");
    if (file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    if (fscanf(file, "%ld", virtual_memory) != 1) {
        perror("fscanf");
        exit(EXIT_FAILURE);
    }
    fclose(file);
    *virtual_memory *= (sysconf(_SC_PAGESIZE) >> 10); // 转换为KB
    *virtual_memory = (*virtual_memory >> 10); // 转换为MB
    // 读取实际物理内存使用（从 /proc/self/status）
    file = fopen("/proc/self/status", "r");
    if (file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    *physical_memory = 0;
    while (fgets(buffer, sizeof(buffer), file)) {
        if (sscanf(buffer, "VmRSS: %ld kB", physical_memory) == 1) {
            break;
        }
    }
    fclose(file);

    // 读取CPU使用（从 /proc/self/stat）
    long jiffies;
    file = fopen("/proc/self/stat", "r");
    if (file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < 13; i++) {
        fscanf(file, "%s", buffer); // 跳过前13项
    }
    fscanf(file, "%ld", &jiffies); // 读取utime
    fclose(file);

    static long prev_jiffies = 0;
    static long prev_total_jiffies = 0;
    long total_jiffies = sysconf(_SC_CLK_TCK) * sysconf(_SC_NPROCESSORS_ONLN) * sysconf(_SC_CLK_TCK);
    if((total_jiffies - prev_total_jiffies) <= 0){
        *cpu = 0;
    }else{
        *cpu = 100.0 * (jiffies - prev_jiffies) / (total_jiffies - prev_total_jiffies);
    }
    prev_jiffies = jiffies;
    prev_total_jiffies = total_jiffies;
}